# -*- coding: utf-8 -*-
# @Time    : 2023/11/24 10:17
# @Author  : Jonny
# @File    : LuckDingtalkApi.py
# @Describe: 钉钉 API服务层

import requests
import objectpath
import logging
import json
import time
import hmac
import hashlib
import base64
import urllib.parse
from datetime import datetime, timedelta


class LuckDingtalkApi(object):

    def __init__(self, app_key, app_secret, agent_id):
        self.dd_domain = "https://oapi.dingtalk.com"
        self.app_key = app_key
        self.app_secret = app_secret
        self.agent_id = agent_id
        self.access_token = self.read_token()

    # 读取token
    def read_token(self):
        if len(self.app_key) > 0:
            url = f"{self.dd_domain}/gettoken"
            data = {
                "appkey": self.app_key,
                "appsecret": self.app_secret,
            }
            res_json = requests.get(url=url, params=data).json()
            return objectpath.Tree(res_json).execute("$.access_token")

    # 读取webhook
    def read_webhook(self, robot_secret, robot_access_token):
        timestamp = str(round(time.time() * 1000))
        secret_enc = robot_secret.encode('utf-8')
        string_to_sign = '{}\n{}'.format(timestamp, robot_secret)
        string_to_sign_enc = string_to_sign.encode('utf-8')
        hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
        sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
        webhook = f"{self.dd_domain}/robot/send?access_token={robot_access_token}&timestamp={timestamp}&sign={sign}"
        return webhook

    # 读取全部部门id
    def read_all_deptid(self):
        url = f"{self.dd_domain}/department/list"
        data = {
            "access_token": self.access_token,
        }
        res_json = requests.get(url=url, params=data).json()
        dept_list = list(objectpath.Tree(res_json).execute("$..*[@.name is not null].id"))

        return dept_list

    # 读取指定部门下的用户
    def read_dept_user_by_deptid(self, deptid: str):
        url = f"{self.dd_domain}/user/getDeptMember"
        data = {
            "access_token": self.access_token,
            "deptId": deptid,
        }
        res_json = requests.get(url=url, params=data).json()

        return res_json

    # 读取全部人员id
    def read_all_userid(self):
        userid_list = list()
        all_deptid = self.read_all_deptid()
        for deptid in all_deptid:
            res_json = self.read_dept_user_by_deptid(deptid)
            userid = objectpath.Tree(res_json).execute("$.userIds")
            userid_list.extend(userid)

        return userid_list

    # 读取指定用户的详情
    def read_user_info(self, userid):
        url = f"{self.dd_domain}/topapi/v2/user/get"
        data = {
            "access_token": self.access_token,
            "userid": userid,
        }
        res_json = requests.get(url=url, params=data).json()

        userIds_list = list(objectpath.Tree(res_json).execute("$..*[@.userid is not null].(mobile, userid)"))
        userInfo = userIds_list[0]

        return {userInfo.get("mobile"): userInfo.get("userid")}

    # 读取全部人员信息
    def read_all_user_info(self):
        user_info_dict = dict()
        all_userid = self.read_all_userid()
        for userid in all_userid:
            user_info = self.read_user_info(userid)
            user_info_dict.update(user_info)

        return user_info_dict

    # 通过钉钉群机器人发送群消息
    def send_msg_by_robot(self, robot_secret, robot_access_token, content):
        # 构造钉钉消息头
        headers = {'Content-Type': 'application/json'}

        # 向hook地址发送post请求
        try:
            webhook = self.read_webhook(robot_secret, robot_access_token)
            res = requests.post(webhook, data=json.dumps(content), headers=headers)
            res = res.json()
        except Exception as e:
            logging.error("通过钉钉群机器人发送群消息异常：%s" % e)
            res = None
        return res

    # 发送个人钉钉消息
    def send_msg_to_person(self, data):
        url = f"{self.dd_domain}/topapi/message/corpconversation/asyncsend_v2?access_token={self.access_token}"
        try:
            res = requests.post(url=url, params=data)
            res = res.json()
        except Exception as e:
            logging.error("发送个人钉钉链接消息异常：%s" % e)
            res = None
        return res
